package com.triplelink.util;

import java.lang.reflect.Field;

import com.triplelink.annotations.ClassType;
import com.triplelink.annotations.Id;
import com.triplelink.exception.TripleLinkException;

public class EntityUtil
{	
	public static String getId(Object entity) throws IllegalArgumentException, IllegalAccessException {
		
		Class<?> currentClass = entity.getClass();
		
		while (currentClass != null)
		{
			for (Field field : currentClass.getDeclaredFields()) {
				
				field.setAccessible(true);
				
				Id semanticId = field.getAnnotation(Id.class);
				
				if (semanticId != null) {
					
					Object idObj = field.get(entity);
					
					
					if (idObj != null)
					{
						return idObj.toString();
					}
					
					return null;
				}
			}
			
			currentClass = currentClass.getSuperclass();
		}
		
		throw new TripleLinkException(getMsgNoIdFoud(entity.getClass()));
	}
	
	public static String getIdOrCreate(Object entity) throws IllegalArgumentException, IllegalAccessException
	{
		String id = null;
		
		Class<?> currentClass = entity.getClass();
		
		while (currentClass != null)
		{
			for (Field field : currentClass.getDeclaredFields())
			{
				field.setAccessible(true);
				
				Id semanticId = field.getAnnotation(Id.class);
				
				if (semanticId != null)
				{
					Object idObj = field.get(entity);
					
					if (idObj == null)
					{
						id = generateId(entity);
						field.set(entity, id);
					}
					else
					{
						id = idObj.toString();
					}
					
					return id;
				}
			}
			
			currentClass = currentClass.getSuperclass();
		}
		
		throw new TripleLinkException(getMsgNoIdFoud(entity.getClass()));
	}
	
	public static String generateId(Object entity)
	{
		return entity.getClass().getAnnotation(ClassType.class).type() + "/" + java.util.UUID.randomUUID();
	}
	
	public static void putId(Object entity, String id) throws IllegalArgumentException, IllegalAccessException
	{
		Class<?> currentClass = entity.getClass();
		
		while (currentClass != null)
		{
			for (Field field : currentClass.getDeclaredFields()) {
				
				field.setAccessible(true);
				
				Id semanticId = field.getAnnotation(Id.class);
				
				if (semanticId != null)
				{
					field.set(entity, id);
					return;
				}
			}
			
			currentClass = currentClass.getSuperclass();
		}
		
		throw new TripleLinkException(getMsgNoIdFoud(entity.getClass()));
	}
	
	public static String getMsgNoIdFoud(Class<?> classe) {
		
		return "No annotation @" + Id.class.getSimpleName() + " found in " + classe.getName() + " hierarchy!";
	}
}
